/* modules/console.c 
 * 
 * Copyright (C) 2021, 2022 intirain. 
 *
 * This file is part of evx. 
 * 
 * evx is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version. 
 * 
 * evx is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with evx. If not, see <https://www.gnu.org/licenses/>
 */ 




#include <sys/types.h>

#include <kernel/init.h>
#include <kernel/module.h>
#include <kernel/tty.h>
#include <kernel/kmlog.h>

#include <modules/serial.h>

#include <arch/io.h>
#include <arch/types.h>


int serial_putc(char);
static int put_kmlog(void);

struct tty serial0_tty = {
	.dev_name = "ttyS0", 
	.priv_data = COM0, 
	.flags = 0, 
	.putc = serial_putc, 
	.getc = NULL
};


static int com_init(__io_t p) {
	outb(0x80, p + 3);
	outb(0x30, p + 0);
	outb(0x00, p + 1);

	outb(0x03, p + 3);
	outb(0x0b, p + 4);
	outb(0x0d, p + 1);

	inb(p);

	return 0;
}

/* as i know, this only runs on x86 */

int __init init_serial(void) {
	com_init(COM0);
	put_kmlog();

	return tty_register(&serial0_tty);
}

int serial_write(__io_t p, char c) {
	while (!(inb(p + 5) & 0x20));

	outb(c, p);

	return 0;
}


int serial_putc(char c) {
	if (c == '\n') 
		serial_write(COM0, '\r');

	return serial_write(COM0, c);
}


static int put_kmlog(void) {
	char *s;

	for (s = kmlog_buf; *s; s++) {
		if (s > kmlog_buf + KMLOG_SIZE) 
			s = kmlog_buf;

		serial_putc(*s);
	}

	return 0;
}


module_init(init_serial);


